package com.gzhryc.shared_device.oem.micro.api.controllers.xcx.v1.cdcz;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.cdcz.code.CDCZCostConfig;
import com.gzhryc.shared_device.cdcz.code.dao.db.CDCZFeeTemplate;
import com.gzhryc.shared_device.cdcz.code.dao.db.CDCZOrder;
import com.gzhryc.shared_device.cdcz.code.dao.db.ChargeSocketSlot;
import com.gzhryc.shared_device.cdcz.code.dao.enums.CDCZOrderEnum;
import com.gzhryc.shared_device.cdcz.code.dao.enums.ChargeSocketSlotEnum;
import com.gzhryc.shared_device.cdcz.code.services.CDCZFeeTemplateService;
import com.gzhryc.shared_device.cdcz.code.services.CDCZOrderService;
import com.gzhryc.shared_device.common.device.dao.db.Device;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.oem.code.ConfigUtils;
import com.gzhryc.shared_device.oem.code.config.dao.enums.EAgreementCode;
import com.gzhryc.shared_device.oem.code.device.CDCZCacheManager;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.member.LoginMember;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberWallet;
import com.gzhryc.shared_device.oem.code.member.services.MemberAgreementService;
import com.gzhryc.shared_device.oem.code.member.services.MemberWalletService;
import com.gzhryc.shared_device.oem.code.order.CacheOrderCollect;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlaceBusinessConfig;
import com.gzhryc.shared_device.oem.code.place.services.PlaceBusinessConfigService;
import com.gzhryc.shared_device.oem.micro.api.MicroConstants;
import com.gzhryc.shared_device.oem.micro.api.OrderCollectManager;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.PayResultCode;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.cdcz.CDCZChargePowerPayRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.cdcz.CDCZChargePowerPayResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.cdcz.CDCZPayResultRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.cdcz.CDCZPayResultResponse;

public class CDCZPayController {

    static Logger log = Logger.getLogger(CDCZPayController.class);

    @Route(value = {"/xcx/v1/cdcz/charge_power/pay.do"}, method = "POST")
    public CDCZChargePowerPayResponse chargePowerPay(HttpServletRequest request, HttpServletResponse response) {
        CDCZChargePowerPayResponse apiResp = new CDCZChargePowerPayResponse(ClientAPICodeConstants.EXECUTE_ERROR, "支付失败，请稍后再试");
        try {
            CDCZChargePowerPayRequest apiReq = WebUtils.getJsonRequest(request, CDCZChargePowerPayRequest.class);
            if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn()) && apiReq.getBody().getSlotNum() != null) {
                String deviceSn = apiReq.getBody().getDeviceSn().trim();
                LoginMember loginMember = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);

                Device device = DeviceService.self().getByDeviceSn(deviceSn);
                if (device == null || device.getPlaceId() == null) {
                    apiResp.setMsg("设备未部署");
                    return apiResp;
                }

                ChargeSocketSlot deviceSlot = CDCZCacheManager.self().getChargeSocketSlot(deviceSn, apiReq.getBody().getSlotNum());
                if (deviceSlot == null) {
                    log.error("未找到{{0}}设备的{{1}}号卡槽", deviceSn, apiReq.getBody().getSlotNum());
                    apiResp.setMsg("未找到" + apiReq.getBody().getSlotNum() + "号插座或设备未上线");
                    return apiResp;
                }

                if (ChargeSocketSlotEnum.State.Working.index().equals(deviceSlot.getState())) {
                    apiResp.setMsg(apiReq.getBody().getSlotNum() + "号插座正在工作");
                    return apiResp;
                }
                
                if (ChargeSocketSlotEnum.State.InMaintenance.index().equals(deviceSlot.getState())) {
                    apiResp.setMsg(apiReq.getBody().getSlotNum() + "号插座正在维修中");
                    return apiResp;
                }
                
                //同意协议
                if (StringTools.isNotBlank(apiReq.getBody().getAppId())) {
                	MemberAgreementService.self().signing(loginMember.getId(), EAgreementCode.RentAgreement.name(), apiReq.getBody().getAppId());
                }

                CDCZFeeTemplate feeTemplate = null;
                PlaceBusinessConfig deviceFunc = PlaceBusinessConfigService.self().getByKeys(device.getPlaceId(), EDeviceFunCode.CDCZ.index());
                if(deviceFunc != null && deviceFunc.getFeeTemplateId() != null) {
                    feeTemplate = CDCZFeeTemplateService.self().getById(deviceFunc.getFeeTemplateId());
                }

                if (feeTemplate == null) {
                    CDCZCostConfig costConfig = ConfigUtils.getCDCZCostConfig();
                    feeTemplate = CDCZFeeTemplateService.buildByDefault(costConfig);
                }

                MemberWallet wallet = MemberWalletService.self().getByMemberId(loginMember.getId());
                if (wallet == null || wallet.getMoney() < feeTemplate.getMinWalletMoney()) {
                    apiResp.setMsg("钱包余额不足，请充值");
                    return apiResp;
                }

                OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE,MicroConstants.PROGRAM_TYPE_NAME);
                operateInfo.setOperator(EOperatorType.Member.index(),loginMember.getFullName());
                if (apiReq.getBody().getTimesMinute() != null && apiReq.getBody().getTimesMinute() > 0) {
                    operateInfo.setOperateNote("购买" + apiReq.getBody().getTimesMinute() + "分钟充电服务");
                } else {
                    operateInfo.setOperateNote("购买充满即停服务");
                }

                if(!CDCZCacheManager.self().lockCDCZSlot(deviceSn,apiReq.getBody().getSlotNum())){
                    log.error("锁定{{0}}设备的{{1}}号卡槽失败", deviceSn, apiReq.getBody().getSlotNum());
                    apiResp.setMsg(apiReq.getBody().getSlotNum() + "号插座繁忙，请稍后再试");
                    return apiResp;
                }

                CacheOrderCollect orderCollect = OrderCollectManager.buildCDCZCacheOrderCollect(loginMember, device, deviceSlot,
                        feeTemplate, apiReq.getBody().getTimesMinute(), operateInfo);
                if (orderCollect == null) {
                    apiResp.setMsg("创建订单失败，请稍后再试");
                    return apiResp;
                }

                apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                apiResp.getBody().setTradeNo(orderCollect.getCdczOrder().getTradeNo());
                apiResp.getBody().setPayType(EPayType.EWallet.index());
            }
        } catch (Exception e) {
            log.error("创建订单失败，" + e.getMessage(), e);
        }
        return apiResp;
    }

    @Route(value = {"/xcx/v1/cdcz/pay/result.do"}, method = "POST")
    public CDCZPayResultResponse payResult(HttpServletRequest request){
        CDCZPayResultResponse apiResp = new CDCZPayResultResponse(ClientAPICodeConstants.NULL_DATA, "未找到支付结果");
        try {
            CDCZPayResultRequest apiReq = WebUtils.getJsonRequest(request, CDCZPayResultRequest.class);
            if (apiReq != null && apiReq.getBody().getPayType() != null && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
               if(EPayType.EWallet.index().equals(apiReq.getBody().getPayType())){
                    CDCZOrder deviceOrder = CDCZOrderService.self(new Date()).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (deviceOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (CDCZOrderEnum.State.Working.index().equals(deviceOrder.getState())) {
                            apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                        }else if(CDCZOrderEnum.State.Finish.index().equals(deviceOrder.getState()) ||
                                CDCZOrderEnum.State.Close.index().equals(deviceOrder.getState())){
                            apiResp.getBody().setResultCode(PayResultCode.CLOSE);
                        }else if(CDCZOrderEnum.State.Fail.index().equals(deviceOrder.getState())){
                            apiResp.getBody().setResultCode(PayResultCode.FAIL);
                        }
                    } else {
                        log.error("未找到设备订单，支付类型：{{0}}，业务订单号：{{1}}", EPayType.EWallet.note(), apiReq.getBody().getTradeNo());
                    }
                }else {
	               	 apiResp.setMsg("无效的支付类型");
	                 return apiResp;
	            }
            }
        } catch (Exception e) {
            log.error("获取订单结果失败，" + e.getMessage(), e);
        }
        return apiResp;
    }
}
